﻿//==============================================================================
// File: ShellPresentationModel.cs
// Created: 2010-05-28
// Author: Piotr Włodek, Arkadiusz Świerczek
//==============================================================================
// This file is a part of MAMMOTH project.
// Copyright (C) 2010 AGH University of Science and Technology, Krakow.
// https://caribou.iisg.agh.edu.pl/trac/mammoth
//
// Mammoth is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// Mammoth is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with Mammoth. If not, see http://www.gnu.org/licenses/.
//==============================================================================

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Composition;
using Caliburn.PresentationFramework.ApplicationModel;
using WpfRcp.Controllers;
using WpfRcp.Core.Common;
using WpfRcp.Core.Common.Workbench;
using WpfRcp.Core.Views;
using WpfRcp.Core.Views.Presenters;
using Microsoft.Practices.Composite.Presentation.Commands;
using Microsoft.Practices.ServiceLocation;
using WpfRcp.Core.Services;

namespace WpfRcp.Views.Presenters
{
    [View(typeof(IShell))]
    public class ShellPresentationModel : Presenter, IShellPresentationModel
    {
        private readonly IRcpSettings m_RcpSettings;
        private readonly IServiceLocator m_Container;
        private readonly IWorkbenchService m_WorkbenchService;
        private readonly IApplicationSettings m_Settings;
        private readonly ShellAnimationController m_ShellAnimationController;

        private bool m_PreviousHeaderShowed;
        private IShell m_View;

        public DelegateCommand<object> ExitCommand { get; private set; }
        public DelegateCommand<object> ChangeHeaderVisibilityCommand { get; private set; }
        public DelegateCommand<object> ToggleFulscreenCommand { get; private set; }
        public DelegateCommand<object> OpenAboutViewCommand { get; private set; }
        public DelegateCommand<object> OpenApplicationOptionsCommand { get; private set; }
        public DelegateCommand<object> OpenLogViewCommand { get; private set; }
        public DelegateCommand<object> OpenStatusViewCommand { get; private set; }

        public ShellPresentationModel(
            IRcpSettings rcpSettings,
            IServiceLocator container,
            IWorkbenchService workbenchService,
            ShellMenuController shellMenuController,
            IApplicationSettings settings,
            ShellAnimationController shellAnimationController)
        {
            // Initialize class variables
            m_RcpSettings = rcpSettings;
            m_Container = container;
            m_WorkbenchService = workbenchService;
            m_Settings = settings;
            m_ShellAnimationController = shellAnimationController;

            ExitCommand = new DelegateCommand<object>(ExecuteExitCommand);
            ChangeHeaderVisibilityCommand = new DelegateCommand<object>(ExecuteChangeHeaderVisibilityCommand);
            ToggleFulscreenCommand = new DelegateCommand<object>(ExecuteToggleFulscreenCommand);
            OpenAboutViewCommand = new DelegateCommand<object>(ExecuteAboutCommand);
            OpenApplicationOptionsCommand = new DelegateCommand<object>(ExecuteApplicationOptionsCommand);
            OpenLogViewCommand = new DelegateCommand<object>(ExecuteOpenLogDialogCommand);
            OpenStatusViewCommand = new DelegateCommand<object>(ExecuteOpenStatusViewCommand);

            shellMenuController.SetupMenu(this);
            ((INotifyPropertyChanged) settings).PropertyChanged += (sender, e) =>
            {
                if (e.PropertyName == "IsHeaderVisible")
                {
                    m_ShellAnimationController.Animate(View);
                }
                else if (e.PropertyName == "IsFullScreen")
                {
                    View.IsFullScreen = settings.IsFullScreen;
                }
            };
        }

        private void SaveWindowSettings()
        {
            var settings = m_Container.GetInstance<IApplicationSettings>();
            settings.WindowTop = View.Top;
            settings.WindowLeft = View.Left;
            settings.WindowWidth = View.Width;
            settings.WindowHeight = View.Height;
            settings.IsMaximized = View.IsMaximized;
        }

        public IShell View
        {
            get { return m_View; }
        }

        public IRcpSettings RcpSettings
        {
            get { return m_RcpSettings; }
        }

        public IApplicationSettings Settings
        {
            get { return m_Settings; }
        }

        [ImportMany(AllowRecomposition = true)]
        public IEnumerable<Lazy<IShutdownQuestion>> Questions { get; set; }

        public override void ViewLoaded(object view, object context)
        {
            m_View = (IShell) view;

            View.Top = m_Settings.WindowTop;
            View.Left = m_Settings.WindowLeft;
            View.Width = m_Settings.WindowWidth;
            View.Height = m_Settings.WindowHeight;
            View.IsMaximized = m_Settings.IsMaximized;
            View.IsFullScreen = m_Settings.IsFullScreen;

            m_ShellAnimationController.Animate(View);
        }

        protected override void OnShutdown()
        {
            base.OnShutdown();

            SaveWindowSettings();
        }

        public override bool CanShutdown()
        {
            foreach (var question in Questions)
            {
                if (!question.Value.Ask())
                {
                    return false;
                }
            }

            return true;
        }

        #region MainView Commands

        #region Exit Command

        private void ExecuteExitCommand(object e)
        {
            Close();
        }

        #endregion

        #region ChangeHeaderVisibility Command

        private void ExecuteChangeHeaderVisibilityCommand(object e)
        {
            m_Settings.IsHeaderVisible = !m_Settings.IsHeaderVisible;
        }

        #endregion

        #region ToggleFulscreen Command

        private void ExecuteToggleFulscreenCommand(object e)
        {
            m_Settings.IsFullScreen = !m_Settings.IsFullScreen;
            if (m_Settings.IsFullScreen)
            {
                m_PreviousHeaderShowed = m_Settings.IsHeaderVisible;
                if (m_Settings.IsHeaderVisible)
                    m_Settings.IsHeaderVisible = false;
            }
            else
            {
                if (m_Settings.IsHeaderVisible != m_PreviousHeaderShowed)
                {
                    m_Settings.IsHeaderVisible = m_PreviousHeaderShowed;
                }
            }
        }

        #endregion

        #region OpenAboutView Command

        private void ExecuteAboutCommand(object e)
        {
            var presenter = m_Container.GetInstance<AboutViewPresentationModel>();
            presenter.View.ShowDialog();
        }

        #endregion

        #region OpenLogView Command

        private void ExecuteOpenLogDialogCommand(object e)
        {
            var item = new ViewItem();
            item.Visual = m_Container.GetInstance<LogViewPresentationModel>().View;

            m_WorkbenchService.Add(item, DockStyle.BottomPanel);
        }

        #endregion

        #region OpenApplicationOptions Command

        private void ExecuteApplicationOptionsCommand(object e)
        {
            var presentationModel = m_Container.GetInstance<ApplicationOptionsViewPresentationModel>();
            presentationModel.View.Show();
        }

        #endregion

        #region OpenStatusView Command

        private void ExecuteOpenStatusViewCommand(object e)
        {
            m_Container.GetInstance<StatusViewPresentationModel>().View.Show();
        }

        #endregion

        #endregion
    }
}